Micron Document
🎖️GitЯра🎖️

Node / meshtastic / Meshtastic-Android / files / core / data / src / commonMain / kotlin / org / meshtastic / core / data / manager / FromRadioPacketHandlerImpl.kt

Displaying Raw • Download

core/data/src/commonMain/kotlin/org/meshtastic/core/data/manager/FromRadioPacketHandlerImpl.kt 2d20cd8a4708e2ef66e98d5259f3a97ec93f240a (2d20cd8a) Text, 10.11 KB

T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.data.manager

Tff7b72import T7ee787co.touchlab.kermit.Logger
Tff7b72import T7ee787kotlinx.coroutines.CoroutineScope
Tff7b72import T7ee787kotlinx.coroutines.SupervisorJob
Tff7b72import T7ee787org.koin.core.annotation.Single
Tff7b72import T7ee787org.meshtastic.core.common.util.ioDispatcher
Tff7b72import T7ee787org.meshtastic.core.model.util.isOtaStatusNotification
Tff7b72import T7ee787org.meshtastic.core.repository.FirmwareUpdateStatusRepository
Tff7b72import T7ee787org.meshtastic.core.repository.FromRadioPacketHandler
Tff7b72import T7ee787org.meshtastic.core.repository.LockdownCoordinator
Tff7b72import T7ee787org.meshtastic.core.repository.MeshConfigFlowManager
Tff7b72import T7ee787org.meshtastic.core.repository.MeshConfigHandler
Tff7b72import T7ee787org.meshtastic.core.repository.MqttManager
Tff7b72import T7ee787org.meshtastic.core.repository.Notification
Tff7b72import T7ee787org.meshtastic.core.repository.NotificationManager
Tff7b72import T7ee787org.meshtastic.core.repository.PacketHandler
Tff7b72import T7ee787org.meshtastic.core.repository.RadioInterfaceService
Tff7b72import T7ee787org.meshtastic.core.repository.RadioSessionContext
Tff7b72import T7ee787org.meshtastic.core.repository.ServiceStateWriter
Tff7b72import T7ee787org.meshtastic.core.repository.XModemManager
Tff7b72import T7ee787org.meshtastic.core.resources.Res
Tff7b72import T7ee787org.meshtastic.core.resources.client_notification
Tff7b72import T7ee787org.meshtastic.core.resources.duplicated_public_key_title
Tff7b72import T7ee787org.meshtastic.core.resources.getStringSuspend
Tff7b72import T7ee787org.meshtastic.core.resources.key_verification_final_title
Tff7b72import T7ee787org.meshtastic.core.resources.key_verification_request_title
Tff7b72import T7ee787org.meshtastic.core.resources.key_verification_title
Tff7b72import T7ee787org.meshtastic.core.resources.low_entropy_key_title
Tff7b72import T7ee787org.meshtastic.proto.ClientNotification
Tff7b72import T7ee787org.meshtastic.proto.FromRadio

T8b949e/** Implementation of [FromRadioPacketHandler] that dispatches [FromRadio] variants to specialized handlers. */
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffLongParameterListTa5d6ff"Tb4b4b4)
Tf0883e@Single
Tff7b72class T56d364FromRadioPacketHandlerImplTb4b4b4(
Tff7b72private Tff7b72val Te6edf3serviceStateWriterTb4b4b4: Te6edf3ServiceStateWriterTb4b4b4,
Tff7b72private Tff7b72val Te6edf3configFlowManagerTb4b4b4: Te6edf3LazyTff7b72<Te6edf3MeshConfigFlowManagerTff7b72>Tb4b4b4,
Tff7b72private Tff7b72val Te6edf3configHandlerTb4b4b4: Te6edf3LazyTff7b72<Te6edf3MeshConfigHandlerTff7b72>Tb4b4b4,
Tff7b72private Tff7b72val Te6edf3xmodemManagerTb4b4b4: Te6edf3LazyTff7b72<Te6edf3XModemManagerTff7b72>Tb4b4b4,
Tff7b72private Tff7b72val Te6edf3mqttManagerTb4b4b4: Te6edf3MqttManagerTb4b4b4,
Tff7b72private Tff7b72val Te6edf3packetHandlerTb4b4b4: Te6edf3PacketHandlerTb4b4b4,
Tff7b72private Tff7b72val Te6edf3notificationManagerTb4b4b4: Te6edf3NotificationManagerTb4b4b4,
Tff7b72private Tff7b72val Te6edf3lockdownCoordinatorTb4b4b4: Te6edf3LockdownCoordinatorTb4b4b4,
Tff7b72private Tff7b72val Te6edf3firmwareUpdateStatusRepositoryTb4b4b4: Te6edf3FirmwareUpdateStatusRepositoryTb4b4b4,
Tff7b72private Tff7b72val Te6edf3radioInterfaceServiceTb4b4b4: Te6edf3RadioInterfaceServiceTb4b4b4,
Tb4b4b4) Tb4b4b4: Te6edf3FromRadioPacketHandler Tb4b4b4{

T8b949e// Application-scoped coroutine context for suspend work (e.g. getStringSuspend).
T8b949e// This @Single lives for the entire app lifetime, so the SupervisorJob is never cancelled.
Tff7b72private Tff7b72val Te6edf3scope Tff7b72= Te6edf3CoroutineScopeTb4b4b4(Te6edf3ioDispatcher Tff7b72+ Te6edf3SupervisorJobTb4b4b4(Tb4b4b4)Tb4b4b4)

Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffCyclomaticComplexMethodTa5d6ff"Tb4b4b4)
Tff7b72override Tff7b72fun Td2a8ffhandleFromRadioTb4b4b4(Te6edf3protoTb4b4b4: Te6edf3FromRadioTb4b4b4, Te6edf3sessionTb4b4b4: Te6edf3RadioSessionContextTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3myInfo Tff7b72= Te6edf3protoTb4b4b4.Te6edf3my_info
Tff7b72val Te6edf3metadata Tff7b72= Te6edf3protoTb4b4b4.Te6edf3metadata
Tff7b72val Te6edf3nodeInfo Tff7b72= Te6edf3protoTb4b4b4.Te6edf3node_info
Tff7b72val Te6edf3configCompleteId Tff7b72= Te6edf3protoTb4b4b4.Te6edf3config_complete_id
Tff7b72val Te6edf3mqttProxyMessage Tff7b72= Te6edf3protoTb4b4b4.Te6edf3mqttClientProxyMessage
Tff7b72val Te6edf3queueStatus Tff7b72= Te6edf3protoTb4b4b4.Te6edf3queueStatus
Tff7b72val Te6edf3config Tff7b72= Te6edf3protoTb4b4b4.Te6edf3config
Tff7b72val Te6edf3moduleConfig Tff7b72= Te6edf3protoTb4b4b4.Te6edf3moduleConfig
Tff7b72val Te6edf3channel Tff7b72= Te6edf3protoTb4b4b4.Te6edf3channel
Tff7b72val Te6edf3clientNotification Tff7b72= Te6edf3protoTb4b4b4.Te6edf3clientNotification
Tff7b72val Te6edf3deviceUIConfig Tff7b72= Te6edf3protoTb4b4b4.Te6edf3deviceuiConfig
Tff7b72val Te6edf3fileInfo Tff7b72= Te6edf3protoTb4b4b4.Te6edf3fileInfo
Tff7b72val Te6edf3regionPresets Tff7b72= Te6edf3protoTb4b4b4.Te6edf3region_presets
Tff7b72val Te6edf3xmodemPacket Tff7b72= Te6edf3protoTb4b4b4.Te6edf3xmodemPacket
Tff7b72val Te6edf3lockdownStatus Tff7b72= Te6edf3protoTb4b4b4.Te6edf3lockdown_status

Tff7b72when Tb4b4b4{
Te6edf3myInfo Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Te6edf3configFlowManagerTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3handleMyInfoTb4b4b4(Te6edf3myInfoTb4b4b4, Te6edf3sessionTb4b4b4)

T8b949e// deviceuiConfig arrives immediately after my_info (STATE_SEND_UIDATA). It carries
T8b949e// the device's display, theme, node-filter, and other UI preferences.
Te6edf3deviceUIConfig Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Te6edf3configHandlerTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3handleDeviceUIConfigTb4b4b4(Te6edf3deviceUIConfigTb4b4b4, Te6edf3sessionTb4b4b4)

Te6edf3metadata Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Te6edf3configFlowManagerTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3handleLocalMetadataTb4b4b4(Te6edf3metadataTb4b4b4, Te6edf3sessionTb4b4b4)

Te6edf3nodeInfo Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3configFlowManagerTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3handleNodeInfoTb4b4b4(Te6edf3nodeInfoTb4b4b4, Te6edf3sessionTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3runIfSessionActiveTb4b4b4(Te6edf3sessionTb4b4b4, Ta5d6ff"Ta5d6ffnode-list progressTa5d6ff"Tb4b4b4) Tb4b4b4{
Te6edf3serviceStateWriterTb4b4b4.Te6edf3setConnectionProgressTb4b4b4(Ta5d6ff"Ta5d6ffNodes (Tffd700${Te6edf3configFlowManagerTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3newNodeCountTffd700}Ta5d6ff)Ta5d6ff"Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Te6edf3configCompleteId Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3configFlowManagerTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3handleConfigCompleteTb4b4b4(Te6edf3configCompleteIdTb4b4b4, Te6edf3sessionTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3runIfSessionActiveTb4b4b4(Te6edf3sessionTb4b4b4, Ta5d6ff"Ta5d6fflockdown config completionTa5d6ff"Tb4b4b4) Tb4b4b4{ Te6edf3lockdownCoordinatorTb4b4b4.Te6edf3onConfigCompleteTb4b4b4(Tb4b4b4) Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Te6edf3mqttProxyMessage Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72>
Te6edf3runIfSessionActiveTb4b4b4(Te6edf3sessionTb4b4b4, Ta5d6ff"Ta5d6ffMQTT proxy messageTa5d6ff"Tb4b4b4) Tb4b4b4{
Te6edf3mqttManagerTb4b4b4.Te6edf3handleMqttProxyMessageTb4b4b4(Te6edf3mqttProxyMessageTb4b4b4)
Tb4b4b4}

Te6edf3queueStatus Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72>
Te6edf3runIfSessionActiveTb4b4b4(Te6edf3sessionTb4b4b4, Ta5d6ff"Ta5d6ffqueue statusTa5d6ff"Tb4b4b4) Tb4b4b4{ Te6edf3packetHandlerTb4b4b4.Te6edf3handleQueueStatusTb4b4b4(Te6edf3queueStatusTb4b4b4) Tb4b4b4}

Te6edf3config Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Te6edf3configHandlerTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3handleDeviceConfigTb4b4b4(Te6edf3configTb4b4b4, Te6edf3sessionTb4b4b4)

Te6edf3moduleConfig Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Te6edf3configHandlerTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3handleModuleConfigTb4b4b4(Te6edf3moduleConfigTb4b4b4, Te6edf3sessionTb4b4b4)

Te6edf3channel Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Te6edf3configHandlerTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3handleChannelTb4b4b4(Te6edf3channelTb4b4b4, Te6edf3sessionTb4b4b4)

Te6edf3fileInfo Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Te6edf3configFlowManagerTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3handleFileInfoTb4b4b4(Te6edf3fileInfoTb4b4b4, Te6edf3sessionTb4b4b4)

T8b949e// region_presets arrives during the handshake (after metadata, before channels). It tells the client
T8b949e// which modem presets are legal per LoRa region. Absent on firmware < 2.8.
Te6edf3regionPresets Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Te6edf3configHandlerTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3handleRegionPresetsTb4b4b4(Te6edf3regionPresetsTb4b4b4, Te6edf3sessionTb4b4b4)

Te6edf3xmodemPacket Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72>
Te6edf3runIfSessionActiveTb4b4b4(Te6edf3sessionTb4b4b4, Ta5d6ff"Ta5d6ffXModem packetTa5d6ff"Tb4b4b4) Tb4b4b4{ Te6edf3xmodemManagerTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3handleIncomingXModemTb4b4b4(Te6edf3xmodemPacketTb4b4b4) Tb4b4b4}

Te6edf3lockdownStatus Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72>
Te6edf3runIfSessionActiveTb4b4b4(Te6edf3sessionTb4b4b4, Ta5d6ff"Ta5d6fflockdown statusTa5d6ff"Tb4b4b4) Tb4b4b4{
Te6edf3lockdownCoordinatorTb4b4b4.Te6edf3handleLockdownStatusTb4b4b4(Te6edf3lockdownStatusTb4b4b4)
Tb4b4b4}

Te6edf3clientNotification Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Te6edf3handleClientNotificationTb4b4b4(Te6edf3clientNotificationTb4b4b4, Te6edf3sessionTb4b4b4)

T8b949e// Firmware rebooted without a transport-level disconnect (common on serial/TCP).
T8b949e// Re-handshake immediately rather than waiting for the 30s stall guard.
Te6edf3protoTb4b4b4.Te6edf3rebooted Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3w Tb4b4b4{ Ta5d6ff"Ta5d6ffFirmware rebooted (rebooted=Tffd700${Te6edf3protoTb4b4b4.Te6edf3rebootedTffd700}Ta5d6ff), re-initiating handshakeTa5d6ff" Tb4b4b4}
Te6edf3configFlowManagerTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3triggerWantConfigTb4b4b4(Te6edf3sessionTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffrunIfSessionActiveTb4b4b4(Te6edf3sessionTb4b4b4: Te6edf3RadioSessionContextTb4b4b4, Te6edf3operationTb4b4b4: Tffa657StringTb4b4b4, Te6edf3blockTb4b4b4: Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3radioInterfaceServiceTb4b4b4.Te6edf3runIfSessionActiveTb4b4b4(Te6edf3sessionTb4b4b4, Te6edf3blockTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3d Tb4b4b4{ Ta5d6ff"Ta5d6ffDiscarding Tffd700$Te6edf3operationTa5d6ff from stale transport sessionTa5d6ff" Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffhandleClientNotificationTb4b4b4(Te6edf3cnTb4b4b4: Te6edf3ClientNotificationTb4b4b4, Te6edf3sessionTb4b4b4: Te6edf3RadioSessionContextTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3admitted Tff7b72=
Te6edf3radioInterfaceServiceTb4b4b4.Te6edf3runIfSessionActiveTb4b4b4(Te6edf3sessionTb4b4b4) Tb4b4b4{ Te6edf3serviceStateWriterTb4b4b4.Te6edf3setClientNotificationTb4b4b4(Te6edf3cnTb4b4b4) Tb4b4b4}
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3admittedTb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3d Tb4b4b4{ Ta5d6ff"Ta5d6ffDiscarding client notification from stale transport sessionTa5d6ff" Tb4b4b4}
Tff7b72return
Tb4b4b4}
Te6edf3radioInterfaceServiceTb4b4b4.Te6edf3launchSessionWorkTb4b4b4(
Te6edf3scope Tff7b72= Te6edf3scopeTb4b4b4,
Te6edf3session Tff7b72= Te6edf3sessionTb4b4b4,
Te6edf3onRejected Tff7b72= Tb4b4b4{ Te6edf3LoggerTb4b4b4.Te6edf3d Tb4b4b4{ Ta5d6ff"Ta5d6ffSkipping client alert from stale transport sessionTa5d6ff" Tb4b4b4} Tb4b4b4}Tb4b4b4,
Tb4b4b4) Tb4b4b4{
Te6edf3dispatchClientNotificationTb4b4b4(Te6edf3cnTb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffdispatchClientNotificationTb4b4b4(Te6edf3cnTb4b4b4: Te6edf3ClientNotificationTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3cnTb4b4b4.Te6edf3isOtaStatusNotificationTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3firmwareUpdateStatusRepositoryTb4b4b4.Te6edf3statusTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3isOtaUpdateActiveTb4b4b4) Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{ Ta5d6ff"Ta5d6ffOTA status ClientNotification received; skipping duplicate generic alertTa5d6ff" Tb4b4b4}
Tff7b72return
Tb4b4b4}

Tff7b72val Te6edf3inform Tff7b72= Te6edf3cnTb4b4b4.Te6edf3key_verification_number_inform
Tff7b72val Te6edf3request Tff7b72= Te6edf3cnTb4b4b4.Te6edf3key_verification_number_request
Tff7b72val Te6edf3verificationFinal Tff7b72= Te6edf3cnTb4b4b4.Te6edf3key_verification_final
Tff7b72val Tb4b4b4(Te6edf3titleTb4b4b4, Te6edf3typeTb4b4b4) Tff7b72=
Tff7b72when Tb4b4b4{
Te6edf3inform Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{ Ta5d6ff"Ta5d6ffKey verification inform receivedTa5d6ff" Tb4b4b4}
Te6edf3PairTb4b4b4(Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3key_verification_titleTb4b4b4)Tb4b4b4, Te6edf3NotificationTb4b4b4.Te6edf3TypeTb4b4b4.Te6edf3InfoTb4b4b4)
Tb4b4b4}

Te6edf3request Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{ Ta5d6ff"Ta5d6ffKey verification request receivedTa5d6ff" Tb4b4b4}
Te6edf3PairTb4b4b4(Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3key_verification_request_titleTb4b4b4)Tb4b4b4, Te6edf3NotificationTb4b4b4.Te6edf3TypeTb4b4b4.Te6edf3InfoTb4b4b4)
Tb4b4b4}

Te6edf3verificationFinal Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3i Tb4b4b4{ Ta5d6ff"Ta5d6ffKey verification final receivedTa5d6ff" Tb4b4b4}
Te6edf3PairTb4b4b4(Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3key_verification_final_titleTb4b4b4)Tb4b4b4, Te6edf3NotificationTb4b4b4.Te6edf3TypeTb4b4b4.Te6edf3InfoTb4b4b4)
Tb4b4b4}

Te6edf3cnTb4b4b4.Te6edf3duplicated_public_key Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3w Tb4b4b4{ Ta5d6ff"Ta5d6ffDuplicated public key notification receivedTa5d6ff" Tb4b4b4}
Te6edf3PairTb4b4b4(Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3duplicated_public_key_titleTb4b4b4)Tb4b4b4, Te6edf3NotificationTb4b4b4.Te6edf3TypeTb4b4b4.Te6edf3WarningTb4b4b4)
Tb4b4b4}

Te6edf3cnTb4b4b4.Te6edf3low_entropy_key Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3LoggerTb4b4b4.Te6edf3w Tb4b4b4{ Ta5d6ff"Ta5d6ffLow entropy key notification receivedTa5d6ff" Tb4b4b4}
Te6edf3PairTb4b4b4(Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3low_entropy_key_titleTb4b4b4)Tb4b4b4, Te6edf3NotificationTb4b4b4.Te6edf3TypeTb4b4b4.Te6edf3WarningTb4b4b4)
Tb4b4b4}

Tff7b72else Tff7b72-Tff7b72> Te6edf3PairTb4b4b4(Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3client_notificationTb4b4b4)Tb4b4b4, Te6edf3NotificationTb4b4b4.Te6edf3TypeTb4b4b4.Te6edf3InfoTb4b4b4)
Tb4b4b4}

Te6edf3notificationManagerTb4b4b4.Te6edf3dispatchTb4b4b4(
Te6edf3NotificationTb4b4b4(Te6edf3title Tff7b72= Te6edf3titleTb4b4b4, Te6edf3type Tff7b72= Te6edf3typeTb4b4b4, Te6edf3message Tff7b72= Te6edf3cnTb4b4b4.Te6edf3messageTb4b4b4, Te6edf3category Tff7b72= Te6edf3NotificationTb4b4b4.Te6edf3CategoryTb4b4b4.Te6edf3AlertTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Served by rngit 1.5.0 - Generated in 0.07s